package utilities;

import java.io.File;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

/**
 *
 * @author hz
 */
public class Encryptor {

    public Encryptor() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        try {
            keygen = KeyGenerator.getInstance("DES");
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        key = keygen.generateKey();

        try {
            eCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            deCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        } catch (NoSuchPaddingException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        try {
            eCipher.init(Cipher.ENCRYPT_MODE, key);
            deCipher.init(Cipher.DECRYPT_MODE, key);
        } catch (InvalidKeyException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }
    }

    public boolean encrypt(File input) throws FileNotFoundException, IOException, IllegalBlockSizeException, BadPaddingException {
        FileInputStream in = null;

        try {
            in = new FileInputStream(input);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        plainData = new byte[(int) input.length()];

        try {
            in.read(plainData);
        } catch (IOException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        try {
            encryptedData = eCipher.doFinal(plainData);
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        } catch (BadPaddingException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        FileOutputStream target = null;
        try {
            target = new FileOutputStream(input);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        try {
            target.write(encryptedData);
            target.close();
        } catch (IOException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        return true;
    }

    public String encrypt(String line) throws IOException, IllegalBlockSizeException, BadPaddingException {
        InputStream in = null;

        plainData = new byte[(int) line.length()];

        in = new ByteArrayInputStream(line.getBytes());

        try {
            in.read(plainData);
        } catch (IOException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        try {
            encryptedData = eCipher.doFinal(plainData);
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        } catch (BadPaddingException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        return new String(encryptedData);
    }

    public boolean decrypt(File input) throws FileNotFoundException, IOException, IllegalBlockSizeException, BadPaddingException {
        FileInputStream in = null;

        try {
            in = new FileInputStream(input);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        plainData = new byte[(int) input.length()];

        try {
            in.read(plainData);
        } catch (IOException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        try {
            decryptedData = deCipher.doFinal(plainData);
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        } catch (BadPaddingException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        FileOutputStream target = null;
        try {
            target = new FileOutputStream(input);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        try {
            target.write(decryptedData);
        } catch (IOException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        try {
            target.close();
        } catch (IOException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        return true;
    }

    public String decrypt(String line) throws IOException, IllegalBlockSizeException, BadPaddingException {
        InputStream in = null;

        plainData = new byte[(int) line.length()];

        in = new ByteArrayInputStream(line.getBytes());

        try {
            in.read(plainData);
        } catch (IOException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        try {
            decryptedData = eCipher.doFinal(plainData);
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        } catch (BadPaddingException ex) {
            Logger.getLogger(Encryptor.class.getName()).log(Level.SEVERE, null, ex);
            throw ex;
        }

        return new String(decryptedData);
    }
    byte[] plainData;
    byte[] encryptedData;
    byte[] decryptedData;
    KeyGenerator keygen;
    SecretKey key;
    Cipher eCipher;
    Cipher deCipher;
}
